﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using itau.im.entidade;
using itau.im.dado;
using EnterpriseLibraryWrapper;

namespace itau.im.negocio
{
    public class CalendarioBS : ICalendarioBS
    {
        #region Metodos

        public IList<PracaCalendario> ObterPracasCalendario()
        {
            IList<PracaCalendario> listaRetorno = null;

            try
            {
                ICalendarioDAO objDAO = DaoFactory.getCalendarioDAO();

                listaRetorno = objDAO.ObterPracasCalendario();

                return listaRetorno;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            finally
            {
                listaRetorno = null;
            }

            return new List<PracaCalendario>();
        }

        public int CalcularDiasCorridosEntre(DateTime data1, DateTime data2)
        {
            int diascorridosentre = 0;

            ICalendarioDAO calendarioDAO = null;

            try
            {
                calendarioDAO = DaoFactory.getCalendarioDAO();
                diascorridosentre = calendarioDAO.CalcularDiasCorridosEntre(data1, data2);
                return diascorridosentre;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            finally
            {
                calendarioDAO = null;
            }
            return diascorridosentre = 0;
        }

        public IList<DiaInfo> CalcularDiasCorridosPorDiasUteis(DateTime dataReferencia, int diasUteis)
        {
            int diasAno = 365;
            int menorBaseDU = 252;
            int qtdFdsAno = 96;
            int qtdFeriadosAno = 365 - menorBaseDU - qtdFdsAno;
            IList<DiaInfo> listaDC;

            int resto;
            CalendarioReguaBS calReg;

            int maxQtdAnos = Math.DivRem(diasUteis, menorBaseDU, out resto) + 1; //Quantidade máxima de anos do período
            int maxDC = Math.DivRem((diasUteis + (maxQtdAnos * qtdFeriadosAno)) * diasAno, menorBaseDU, out resto) + 1; //Quantidade máxima possível de DC

            try
            {
                listaDC = new List<DiaInfo>();

                calReg = new CalendarioReguaBS(dataReferencia, dataReferencia.AddDays(maxDC));

                IEnumerable<KeyValuePair<string, DiaInfo>> listaMesmoDU = calReg.Regua.Where(p => p.Value.DiasUteis.Equals(diasUteis));

                if (listaMesmoDU != null)
                {
                    foreach (KeyValuePair<string, DiaInfo> item in listaMesmoDU)
                    {
                        listaDC.Add(item.Value);
                    }
                }

                return listaDC;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            finally
            {
                calReg = null;
            }

            return new List<DiaInfo>();
        }

        public IList<int> NormalizarDiasCorridosParaDiasCorridosUteis(DateTime dataReferencia, IList<int> listaDiasCorridos)
        {
            int maxDiasNaoUteisConsecutivos = 7;
            int diasCorridos;
            IList<int> listaRetorno;
            CalendarioReguaBS calReg;
            KeyValuePair<string, DiaInfo> diaInfo;

            int maiorDiaCorrido = listaDiasCorridos.Max();

            try
            {
                calReg = new CalendarioReguaBS(dataReferencia, dataReferencia.AddDays(maiorDiaCorrido + maxDiasNaoUteisConsecutivos));
                listaRetorno = new List<int>();

                for (int i = 0; i < listaDiasCorridos.Count; i++)
                {
                    if (i > 0)
                    {
                        //Ordena e desloca os dias corridos, se coincidentes ou desordenados
                        if (listaDiasCorridos[i - 1] >= listaDiasCorridos[i])
                        {
                            listaDiasCorridos[i] = listaDiasCorridos[i - 1] + 1;
                        }
                    }

                    diasCorridos = listaDiasCorridos[i];

                    //Itera até encontrar um dia útil
                    do
                    {
                        diaInfo = calReg.Regua.FirstOrDefault(p => p.Value.DiasCorridos == diasCorridos);
                        diasCorridos++;
                    }
                    while (!diaInfo.Equals(default(KeyValuePair<string, DiaInfo>)) &&
                           !diaInfo.Value.EhDiaUtil &&
                            diasCorridos < maiorDiaCorrido);

                    listaDiasCorridos[i] = diaInfo.Value.DiasCorridos;

                    listaRetorno.Add(diaInfo.Value.DiasCorridos);
                }

                return listaRetorno;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            finally
            {
                calReg = null;
                listaRetorno = null;
            }

            return new List<int>();
        }

        public int CalcularDiasUteisEntre(DateTime data1, DateTime data2)
        {
            ICalendarioDAO calendarioDAO = null;

            try
            {
                calendarioDAO = DaoFactory.getCalendarioDAO();
                return calendarioDAO.CalcularDiasUteisEntre(data1, data2);
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            finally
            {
                calendarioDAO = null;
            }
            //return diasuteisentre = 0;
            return 0;
        }

        public IList<string> ObtemFeriadosNacionaisIntervalo(DateTime data1, DateTime data2)
        {

            ICalendarioDAO calendarioDAO = null;

            try
            {
                calendarioDAO = DaoFactory.getCalendarioDAO();
                return calendarioDAO.ObtemFeriadosNacionaisIntervalo(data1, data2);

            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            finally
            {
                calendarioDAO = null;
            }
            return null;
        }

        public bool EhFeriadoNacional(DateTime data)
        {
            ICalendarioDAO calendarioDAO = null;

            try
            {
                calendarioDAO = DaoFactory.getCalendarioDAO();
                return calendarioDAO.EhFeriadoNacional(data);
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            finally
            {
                calendarioDAO = null;
            }

            return false;
        }

        public void ConfigurarCalendarioGerador(int diasExtensaoCurva)
        {
            ICalendarioDAO calendarioDAO = null;

            try
            {
                calendarioDAO = DaoFactory.getCalendarioDAO();
                calendarioDAO.ConfigurarCalendarioGerador(diasExtensaoCurva);
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            finally
            {
                calendarioDAO = null;
            }
        }

        #endregion

    }
}
